package com.tonggedata.dataapi.controller;

import cn.hutool.core.math.MathUtil;
import cn.hutool.core.util.StrUtil;
import com.tonggedata.dataapi.dto.*;
import com.tonggedata.dataapi.entity.ApiGroup;
import com.tonggedata.dataapi.service.ApiConfigService;
import com.tonggedata.dataapi.service.ApiGroupService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.apache.dolphinscheduler.api.aspect.AccessLogAnnotation;
import org.apache.dolphinscheduler.api.controller.BaseController;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.dao.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import org.apache.dolphinscheduler.common.utils.ParameterUtils;

import org.apache.dolphinscheduler.api.exceptions.ApiException;

import java.security.SecureRandom;
import java.util.*;

import static org.apache.dolphinscheduler.api.enums.Status.*;

/**
 * api业务分组表
 *
 * @author tonggedata
 * @date 2022-06-15 20:29:53
 */
@RestController
@AllArgsConstructor
@RequestMapping("/dataapi/group" )
@Api(value = "api业务分组表Controller" , tags = "api业务分组表管理" , description = "api业务分组表管理相关接口" )
public class ApiGroupController extends BaseController {

    @Autowired
    private ApiGroupService apiGroupService;

    @Autowired
    private ApiConfigService apiConfigService;

    @ApiOperation(value = "queryApiGroupListPaging" , notes = "QUERY_ApiGroup_LIST_PAGING_NOTES" )
    @ApiImplicitParams({
            @ApiImplicitParam(name = "searchVal" , value = "SEARCH_VAL" , dataType = "String" ),
            @ApiImplicitParam(name = "pageNo" , value = "PAGE_NO" , required = true, dataType = "Int" , example = "1" ),
            @ApiImplicitParam(name = "pageSize" , value = "PAGE_SIZE" , required = true, dataType = "Int" , example = "20" )
    })
    @GetMapping()
    @ResponseStatus(HttpStatus.OK)
    @ApiException(DATA_API_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser" )
    public Result queryApiGroupListPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                                          @RequestParam(value = "searchVal" , required = false) String searchVal,
                                          @RequestParam("pageNo" ) Integer pageNo,
                                          @RequestParam("pageSize" ) Integer pageSize) {
        Result result = checkPageParams(pageNo, pageSize);
        if (!result.checkResult()) {
            return result;
        }
        searchVal = ParameterUtils.handleEscapes(searchVal);
        return apiGroupService.queryApiGroupListPaging(loginUser, searchVal, pageNo, pageSize);
    }

    /**
     * Group的查询，如果groupName不为空，那么查询对应group及其下面的api,如果apiName不为空，那么就查询对应的api和其分组,
     * 如果都为空那么就查询全部group及全部api
     * @param loginUser
     * @param groupName
     * @param apiName
     * @return
     */
    @ApiOperation(value = "queryApiGroupList" , notes = "QUERY_ApiGroup_LIST_BY_TYPE_NOTES" )
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name" , value = "名称" , required = false, dataType = "String" )
    })
    @GetMapping(value = "/getAll" )
    @ResponseStatus(HttpStatus.OK)
    @ApiException(DATA_API_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser" )
    public Result queryApiGroupList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                                    @RequestParam(value = "groupName" ,required = false) String groupName,
                                    @RequestParam(value = "apiName" ,required = false) String apiName) {
        Map<String, Object> result=null;
        if(StrUtil.isEmpty(apiName)){
            result = apiGroupService.queryApiGroupList(loginUser, groupName);
            List<ApiGroup> groups = (List<ApiGroup>) result.get("data");
            List<ApiGroupDto> groupDtos = new ArrayList<>();
            for (ApiGroup group : groups) {
                ApiGroupDto apiGroupDto = new ApiGroupDto();
                apiGroupDto.set(group);
                Long groupId = group.getId();
                Result apiResult = apiConfigService.queryApiConfigListByGroupId(loginUser, groupId);
                apiGroupDto.setChildren((List<ApiConfigDto>) apiResult.getData());
            }
            result.put("data",groupDtos);
            return returnDataList(result);
        }else{
            apiGroupService.queryApiGroupAndApiConfigList(loginUser,groupName,apiName);
        }

        return returnDataList(result);
    }

    @ApiOperation(value = "queryApiGroup" , notes = "QUERY_ApiGroup_NOTES" )
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id" , value = "ApiGroup_ID" , required = true, dataType = "Int" , example = "100" )

    })
    @GetMapping(value = "/{id}" )
    @ResponseStatus(HttpStatus.OK)
    @ApiException(DATA_API_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser" )
    public Result queryApiGroup(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                                @PathVariable("id" ) int id) {

        Map<String, Object> result = apiGroupService.queryApiGroup(id);
        return returnDataList(result);
    }

    @ApiOperation(value = "createApiGroup" , notes = "CREATE_ApiGroup_NOTES" )
    @PostMapping(value = "/create")
    @ResponseStatus(HttpStatus.CREATED)
    @ApiException(DATA_API_GROUP_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser" )
    public Result createApiGroup(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                                 @RequestParam(value = "name" ,required = false) String groupName,
                                 @RequestParam(value = "desc" ,required = false) String groupDesc) {
        SecureRandom secureRandom = new SecureRandom();
        long id = secureRandom.nextLong();
        ApiGroup apiGroup = new ApiGroup(Math.abs(id),1,groupName,groupDesc,loginUser.getUserName(),loginUser.getUserName(),new Date(),new Date(),0);
        return apiGroupService.insert(loginUser,apiGroup);
    }

    @ApiOperation(value = "updateApiGroup" , notes = "UPDATE_ApiGroup_NOTES" )
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id" , value = "ApiGroup_ID" , required = true, dataType = "Integer" ),
            @ApiImplicitParam(name = "apiGroupParam" , value = "ApiGroup_PARAM" , required = true, dataType = "ApiGroupParamDto" )
    })
    @PutMapping(value = "/{id}" )
    @ResponseStatus(HttpStatus.OK)
    @ApiException(DATA_API_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser" )
    public Result updateApiGroup(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                                 @PathVariable(value = "id" ) Long id,
                                 @RequestBody ApiGroupParamDto apiGroupParam) {
        apiGroupParam.setId(id);
        return apiGroupService.updateApiGroup(apiGroupParam.getId(), loginUser, apiGroupParam);
    }


    @ApiOperation(value = "deleteApiGroup" , notes = "DELETE_ApiGroup_NOTES" )
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id" , value = "ApiGroup_ID" , required = true, dataType = "Int" , example = "100" )
    })
    @DeleteMapping(value = "/{id}" )
    @ResponseStatus(HttpStatus.OK)
    @ApiException(DATA_API_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser" )
    public Result delete(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                         @PathVariable("id" ) int id) {
        return apiGroupService.delete(loginUser, id);
    }


    @ApiOperation(value = "createApiGroup" , notes = "CREATE_ApiGroup_NOTES" )
    @PostMapping()
    @ResponseStatus(HttpStatus.CREATED)
    @ApiException(DATA_API_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser" )
    public Result createApiGroup(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                                 @RequestBody ApiGroupParamDto apiGroupParam) {
        return apiGroupService.createApiGroup(loginUser, apiGroupParam);
    }

}
